/**
 * @author Francesco Rosso, matr 592057
 */

package pcd1112.view;

import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ClientGUI implements ChangeListener {

	private MainFrame FramePrincipale = new MainFrame();
	JScrollPane scrollPanel = new JScrollPane();
	private JTextField confUrl = new JTextField();
	private JTextField rmiHost = new JTextField("localhost");
	private JButton start = new JButton("Start");
	private JButton stop = new JButton("Stop");
	private JComboBox<String> configurationType = new JComboBox<String>();

	private PannelloNodi nodi = new PannelloNodi();
	private final JLabel lblSelectPreferredMode = new JLabel(
			"Select preferred mode");
	private final JPanel top = new JPanel();
	private final JPanel bottom = new JPanel();
	private final JSplitPane splitPane = new JSplitPane();
	private final JSplitPane MainPanel = new JSplitPane(
			JSplitPane.VERTICAL_SPLIT, true);
	private final JSlider slider = new JSlider();
	private final JLabel lblMsecBetweenMessages = new JLabel(
			"msec between messages");
	private final JProgressBar progressBar = new JProgressBar();
	private final JLabel progressText = new JLabel("");
	private final JSpinner msecText = new JSpinner();

	DefaultListModel<String> resultModel = new DefaultListModel<String>();
	JList<String> resultList = new JList<String>(resultModel);

	public JButton getStopButton() {
		return stop;
	}

	public JButton getStartButton() {
		return start;
	}

	public void clearResult() {
		resultModel.clear();
	}

	public void appendResult(String line) {
		resultModel.add(0, line);
	}

	public ClientGUI() {
		FramePrincipale.getContentPane().setLayout(new GridLayout(1, 1, 0, 0));
		FramePrincipale.getContentPane().add(MainPanel);

		top.setLayout(new GridLayout(1, 2, 0, 0));
		top.add(splitPane);
		JPanel opzioni = new JPanel();
		splitPane.setLeftComponent(opzioni);
		GridBagLayout gbl_opzioni = new GridBagLayout();
		gbl_opzioni.columnWidths = new int[] { 30, 1, 100, 30 };
		gbl_opzioni.rowHeights = new int[] { 22, 22, 22, 23, 20, 35, 14, 0 };
		gbl_opzioni.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0 };
		gbl_opzioni.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
				0.0, Double.MIN_VALUE };
		opzioni.setLayout(gbl_opzioni);
		JLabel labUrl = new JLabel("Insert configuration file URL");
		GridBagConstraints gbc_labUrl = new GridBagConstraints();
		gbc_labUrl.anchor = GridBagConstraints.EAST;
		gbc_labUrl.insets = new Insets(0, 0, 5, 5);
		gbc_labUrl.gridx = 0;
		gbc_labUrl.gridy = 0;
		opzioni.add(labUrl, gbc_labUrl);
		GridBagConstraints gbc_confUrl = new GridBagConstraints();
		gbc_confUrl.fill = GridBagConstraints.HORIZONTAL;
		gbc_confUrl.anchor = GridBagConstraints.NORTHWEST;
		gbc_confUrl.insets = new Insets(0, 0, 5, 0);
		gbc_confUrl.gridwidth = 3;
		gbc_confUrl.gridx = 1;
		gbc_confUrl.gridy = 0;
		opzioni.add(confUrl, gbc_confUrl);
		JLabel labRMI = new JLabel("Insert RMI Server URL");
		GridBagConstraints gbc_labRMI = new GridBagConstraints();
		gbc_labRMI.anchor = GridBagConstraints.EAST;
		gbc_labRMI.insets = new Insets(0, 0, 5, 5);
		gbc_labRMI.gridx = 0;
		gbc_labRMI.gridy = 1;
		opzioni.add(labRMI, gbc_labRMI);
		GridBagConstraints gbc_rmiHost = new GridBagConstraints();
		gbc_rmiHost.anchor = GridBagConstraints.NORTH;
		gbc_rmiHost.fill = GridBagConstraints.HORIZONTAL;
		gbc_rmiHost.insets = new Insets(0, 0, 5, 0);
		gbc_rmiHost.gridwidth = 3;
		gbc_rmiHost.gridx = 1;
		gbc_rmiHost.gridy = 1;
		opzioni.add(rmiHost, gbc_rmiHost);
		GridBagConstraints gbc_lblSelectPreferredMode = new GridBagConstraints();
		gbc_lblSelectPreferredMode.anchor = GridBagConstraints.EAST;
		gbc_lblSelectPreferredMode.insets = new Insets(0, 0, 5, 5);
		gbc_lblSelectPreferredMode.gridx = 0;
		gbc_lblSelectPreferredMode.gridy = 2;
		opzioni.add(lblSelectPreferredMode, gbc_lblSelectPreferredMode);
		GridBagConstraints gbc_configurationType = new GridBagConstraints();
		gbc_configurationType.anchor = GridBagConstraints.NORTH;
		gbc_configurationType.fill = GridBagConstraints.HORIZONTAL;
		gbc_configurationType.insets = new Insets(0, 0, 5, 0);
		gbc_configurationType.gridwidth = 3;
		gbc_configurationType.gridx = 1;
		gbc_configurationType.gridy = 2;
		configurationType
				.setToolTipText("Real is mre efficient with smaller amount of nodes (i.e. under 1000)");
		opzioni.add(configurationType, gbc_configurationType);

		configurationType.addItem("Default");
		configurationType.addItem("Real");

		GridBagConstraints gbc_lblMsecBetweenMessages = new GridBagConstraints();
		gbc_lblMsecBetweenMessages.fill = GridBagConstraints.HORIZONTAL;
		gbc_lblMsecBetweenMessages.insets = new Insets(0, 0, 5, 5);
		gbc_lblMsecBetweenMessages.gridx = 0;
		gbc_lblMsecBetweenMessages.gridy = 3;
		opzioni.add(lblMsecBetweenMessages, gbc_lblMsecBetweenMessages);
		msecText.setToolTipText("Max value is 5000");
		msecText.setModel(new SpinnerNumberModel(0, 0, 5000, 1));

		GridBagConstraints gbc_msecText = new GridBagConstraints();
		gbc_msecText.insets = new Insets(0, 0, 5, 5);
		gbc_msecText.gridx = 1;
		gbc_msecText.gridy = 3;
		opzioni.add(msecText, gbc_msecText);
		msecText.addChangeListener(this);
		slider.setPaintLabels(true);
		slider.setValue(0);
		slider.setMaximum(5000);
		GridBagConstraints gbc_slider = new GridBagConstraints();
		gbc_slider.gridwidth = 2;
		gbc_slider.fill = GridBagConstraints.HORIZONTAL;
		gbc_slider.insets = new Insets(0, 0, 5, 0);
		gbc_slider.gridx = 2;
		gbc_slider.gridy = 3;
		opzioni.add(slider, gbc_slider);

		slider.addChangeListener(this);

		JPanel buttons = new JPanel();
		GridBagConstraints gbc_buttons = new GridBagConstraints();
		gbc_buttons.gridwidth = 4;
		gbc_buttons.anchor = GridBagConstraints.NORTH;
		gbc_buttons.insets = new Insets(0, 0, 5, 5);
		gbc_buttons.gridx = 0;
		gbc_buttons.gridy = 5;
		opzioni.add(buttons, gbc_buttons);
		buttons.setLayout(new FlowLayout(FlowLayout.CENTER));
		buttons.add(start);
		buttons.add(stop);
		start.setEnabled(true);
		stop.setEnabled(false);

		GridBagConstraints gbc_progressText = new GridBagConstraints();
		gbc_progressText.anchor = GridBagConstraints.EAST;
		gbc_progressText.insets = new Insets(0, 0, 0, 5);
		gbc_progressText.gridx = 1;
		gbc_progressText.gridy = 6;
		opzioni.add(progressText, gbc_progressText);

		GridBagConstraints gbc_progressBar = new GridBagConstraints();
		gbc_progressBar.gridwidth = 4;
		gbc_progressBar.anchor = GridBagConstraints.NORTH;
		gbc_progressBar.fill = GridBagConstraints.HORIZONTAL;
		gbc_progressBar.gridx = 0;
		gbc_progressBar.gridy = 6;
		progressBar.setToolTipText("Simulations progress");
		opzioni.add(progressBar, gbc_progressBar);
		nodi.setToolTipText("Click on a node to see its information in real time");
		splitPane.setRightComponent(nodi);
		bottom.setLayout(new GridLayout(1, 1, 0, 0));
		resultList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		scrollPanel = new JScrollPane(resultList);
		bottom.add(scrollPanel);
		scrollPanel
				.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		scrollPanel
				.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		MainPanel.add(top);
		MainPanel.add(bottom);
		FramePrincipale.setResizable(true);
		FramePrincipale.pack();
		confUrl.setText("http://www.math.unipd.it/~conti/teaching/PCD1112/project_config.txt");
		opzioni.setSize(200, 200);
		FramePrincipale.setVisible(true);

	}

	public MainFrame getFrame() {
		return FramePrincipale;
	}

	public PannelloNodi getNodi() {
		return nodi;
	}

	public JComboBox<String> getConfigurationType() {
		return configurationType;
	}

	public JSlider getMsecSlider() {
		return slider;
	}

	public JSpinner getMsecText() {
		return msecText;
	}

	public void setProgress(int status, int total) {
		progressText.setText(status + " of " + total);
		progressBar.setValue((int) ((total / 100) * status));
	}

	@Override
	public void stateChanged(ChangeEvent e) {
		if (e.getSource() instanceof JSlider) {
			msecText.setValue(slider.getValue());
		}
		if (e.getSource() instanceof JSpinner) {
			slider.setValue((int) msecText.getValue());
		}
	}

	public JTextField getConfUrl() {
		return confUrl;
	}

	public JTextField getRmiHost() {
		return rmiHost;
	}

}
